/*
 * lrvm.h
 *
 *  Created on: Nov 26, 2011
 *
 */

//#ifndef LRVM_H_
//#define LRVM_H_
#include <iostream>
#include <deque>
#include<vector>
#include <map>
#include<string>

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <string.h>
#include <stdlib.h>
#include <sys/file.h>
#include <dirent.h>



using std::deque;
using std::map;
using std::string;

using namespace std;

//////////////////////CONSTANTS//////////////////////////

#define UNMODIFIED 0
#define MODIFIED 1
#define UNMAPPED 2
#define NOTCOMMITTED 3
#define COMMITTED 4
#define TRANS_BEGUN 5


//////////////////////STRUCTURES///////////////////////////////
typedef struct rvm* rvm_t;
typedef struct transaction* trans_t;

typedef struct rvm_segment* rvm_seg_ptr ;
typedef struct region* region_ptr ;


/*
RVM_SEGMENT Contains the core structure of rvm
*/
struct rvm_segment {
	void *memory;
	const char *segname;
	int state;
	int seg_fd;
	unsigned int size;
	void *logmemory ;
	const char *logname;

};

/*
REGION is a SUBSET of the RVM_SEGMENT that is modified
 */

struct region  {
	rvm_segment *seg_ptr;
	//unsigned int seg_idx;
	unsigned int offset;
	unsigned int size;
	//void *memory ;
};

/*
 TRANSACTION  is structure comprising of
 1. all segments that are modified ,
 2. all regions of segments that are modified
 */

struct transaction {
	rvm_t rvm;
	int numsegs ;
	vector <rvm_segment*> sub_seg_list;
	vector <region*> region_list ;
	int state ;

};


/*
 RVM contains the ROOT Information of Recoverable Virtual Memory Structure
 1. List of segments
 2. List of Transactions
 */

struct rvm {

	const char *rootdir ;
	FILE *log_filepointer;
	int log_handle;
	//map <string,rvm_segment*> seg_list;
	vector <rvm_segment*> seglist ;
	vector <trans_t> rvm_trans_list;

};


struct rvm_log {
	unsigned int rec_len;
	char committed;
	unsigned int segname_len;
	char *segname;
	int offset;
	int len;
	char *data;
	//unsigned int tail_len;
};



/////////////////////FUNCTIONS////////////////////////////////////


rvm_t rvm_init(const char *directory) ;//- Initialize the library with the specified directory as backing store.
void *rvm_map(rvm_t rvm, const char *segname, int size_to_create) ;//- map a segment from disk into memory. If the segment does not already exist, then create it and give it size size_to_create. If the segment exists but is shorter than size_to_create, then extend it until it is long enough. It is an error to try to map the same segment twice.
void rvm_unmap(rvm_t rvm, void *segbase) ;//- unmap a segment from memory.
void rvm_destroy(rvm_t rvm, const char *segname); //- destroy a segment completely, erasing its backing store. This function should not be called on a segment that is currently mapped.
trans_t rvm_begin_trans(rvm_t rvm, int numsegs, void **segbases) ;//- begin a transaction that will modify the segments listed in segbases. If any of the specified segments is already being modified by a transaction, then the call should fail and return (trans_t) -1.

void rvm_about_to_modify(trans_t tid, void *segbase, int offset, int size); //- declare that the library is about to modify a specified range of memory in the specified segment. The segment must be one of the segments specified in the call to rvm_begin_trans. Your library needs to ensure that the old memory has been saved, in case an abort is executed. It is legal call rvm_about_to_modify multiple times on the same memory area.
void rvm_commit_trans(trans_t tid) ;//- commit all changes that have been made within the specified transaction. When the call returns, then enough information should have been saved to disk so that, even if the program crashes, the changes will be seen by the program when it restarts.
void rvm_abort_trans(trans_t tid) ;//- undo all changes that have happened within the specified transaction.
void rvm_truncate_log(rvm_t rvm) ;//- play through any committed or aborted items in the log file(s) and shrink the log file(s) as much as possible.

/////////////////////// INTERNAL FUNCTION ////////////////////////////////
char *generate_filepath(const char *directory,  const char *segname);
rvm_segment* create_segment(const char *segname, int size_to_create, void *seg_block , long int fd );


/////////////////////////////////////////////////////////////////////////

//#endif /* LRVM_H_ */
